package JUC.第05章_中断机制_LockSupport;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * AQS 的底层
 * LockSupport//不需要锁块 synchronized   Lock的Condition
 * park()//阻塞队列        //wait()       和 await()  的   升级版   //
 * unpark()//关闭阻塞队列   //notify()     和 signal() 的   升级版 //
 * wait()和notify() 方法必须要在 同一个同步块 或者方法里面且成对出现使用
 * wait()一定在notify()前面执行
 * 线程先要获得并持有锁，必须在锁块(synchronized或lock)
 * 中必须要先等待后唤醒，线程才能够被唤醒
 *
 * unpark()可以在park()前执行   等于提前唤醒//native方法
 * unpark()发放许可证 用一次+1 但是最大为一
 * park()消耗许可证   为0消耗不了被堵塞  直到再发许可证
 *
 *用于创建锁和其他同步类的基本线程阳塞原语。
 *
 * static Object    getBlocker(Thread t)                        返回提供给尚未解除阻塞的park方法的最新调用的阻止程序对象，如果未阻止,则返回null.
 * static void      park()                                      除非许可证可用，否则禁用当前线程以进行线程调度。
 * static void      park(Object blocker)                        除非许可证可用，否则禁用当前线程以进行线程调度。
 * static void      parkNanos(long nanos)                       除非许可证可用，否则禁用当前线程以进行线程调度，直到指定的等待时间。
 * static void      parkNanos(Object blocker, long nanos)       除非许可证可用，否则禁用当前线程以进行线程调度，直到指定的等待时间。
 * static void      parkUntil(long deadline)                    除非许可证可用，否则禁用当前线程以进行线程调度，直到指定的截止时间。
 * static void      parkUntil(object blocker, long deadline)    除非许可证可用，否则禁用当前线程以进行线程调度,直到指定的截止时间。
 * static void      unpark(Thread thread)                       如果给定线程尚不可用，则购其提供许可。
 *
 */
public class B3_LockSupport介绍 {
    public static void main(String[] args) {

        Thread a = new Thread(()->{
            try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}

            System.out.println("进入->" + Thread.currentThread().getName());
            LockSupport.park();//消耗许可证 -1 为0消耗不了被堵塞
            System.out.println(Thread.currentThread().getName() + " 被唤醒");
        },"a");//park 必须有线程给他发放许可证  才往后执行
        a.start();

        Thread b = new Thread(()->{
            System.out.println("进入->" + Thread.currentThread().getName());
            //给 a发放许可证（注意  这时候 线程a 必须是运行中，否则无效）
            LockSupport.unpark(a);// unpark()发放许可证 用一次+1 但是最大为 1
            System.out.println(Thread.currentThread().getName() + " 唤醒->" + a.getName());

        },"b");//unpark 给指定线程发放许可证
        b.start();

    }
}
